﻿

// version: 1.2.1.0
// author: Genshui Yang
// time: 2016-06-17  
// *************************************************


; (function ($, window, document, undefined) {

    var pluginName = "grid", defaults = { id: '', key: '', title: { label: 'Data Grid Title..' }, cols: [], toolbar: {}, rowindex: false, data: [], colwidth: 80, pageindex: 0, pagesize: 10, height: 400, pager: null, rowbind: null, isfix: true };

    function Plugin(element, options) {
        this.element = $(element);
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        console.log('this.settings.height:' + this.settings.height);
        this.init();
    }

    Plugin.prototype = {

        init: function () {
            if (this.isIE() <= 9) { return false; }
            if (this.settings.id == '') { return false; }
            this.bind();
        },

        bind: function () {

            var setting = this.settings, width = this.element.width();

            var h = this.init_head();
            var b = this.init_body();
            var f = this.init_footer();

            var p = '<div class="panel" style="margin:0;"><div class="panel-heading" style="padding:0 10px;"><div class="row"><div class="col-sm-6"><h4 style="margin:10px 0;"> <i class="fa fa-th"> </i> ' + setting.title.label + '</h4></div><div class="col-sm-6"><div class="pull-right"><div class="' + setting.id + '-pager" >' + f.pagerhtml + '</div></div></div> </div></div></div>';
            if (setting.isfix) {
                var thead = '<div id="' + setting.id + '-thead" style="overflow:hidden;"><table class="table table-striped table-bordered table-hover" style="border:0;margin:0;"><tbody><tr class="active">' + h.html + '</tr></tbody></table></div>';
                var tbody = '<div id="' + setting.id + '-tbody" style=" overflow:auto;background-color:#ffffff;" onscroll="noke_gridscroll(this, \'' + setting.id + '\');"><table class="table table-striped table-bordered table-hover" style="border:0;margin:0;"><tbody>' + b.html + '</tbody></table></div>';
                p += '<div id="' + setting.id + '-table" style="display:none;">' + thead + tbody + f.html + '</div>';
                this.element.html(p);

                var ths = $('#' + setting.id + '-thead .grid-th'), tds = $('#' + setting.id + '-tbody .grid-td'), cols = setting.cols, len = ths.length - 1, twidth = 0;

                for (var i = 0; i < len; i++) {
                    var w = (cols[i].width ? cols[i].width : setting.colwidth);
                    twidth += w;
                    $(ths[i]).width(w);
                    $(tds[i]).width(w);
                }

                var widthT = width - twidth - (setting.checkbox ? 40 : 0) - (setting.rowindex ? 40 : 0) - ((len + 1 + (setting.checkbox ? 1 : 0) + (setting.rowindex ? 1 : 0)) * 8) - 18;
                if(widthT > 0){
                    $(ths[len]).width(widthT).parent().show();
                    $(tds[len]).width(widthT).parent().show();
                }

                //$('#' + setting.id + '-footer').width(width);
                $('#' + setting.id + '-tbody').height(setting.height);


            } else {
                p += '<div id="' + setting.id + '-table" style="display:none;"><div><table class="table table-striped table-bordered table-hover" style="border:0;margin:0;"><tbody><tr class="active">' + h.html + '</tr></tbody><tbody>' + b.html + '</tbody></table></div>' + f.html + '</div>';
                this.element.html(p);
            }
            //this.element.css('');

            // bind event
            this.event_pager();
            this.event_toobar();
            this.event_head();
            this.event_body();

            $('#' + setting.id + '-table').show();
        },

        // build grid head (bind columns)
        init_head: function () {

            var setting = this.settings, thhtml = '';

            if (setting.checkbox) {
                thhtml += '<td style="text-align:center;width:40px;"><div class="grid-checkbox" style=" width:40px;"><input type="checkbox" name="' + setting.id + '" value="ALL_' + setting.id + '" /></div></td>'; // 全选
            }
            if (setting.rowindex) {
                thhtml += '<td style="text-align:center;width:40px;"><div class="grid-no" style=" width:40px;">#</div></td>'; // 行序号
            }

            // bind head expend method
            if (setting.headbind) {
                headbind(columns, setting);
            }

            $(setting.cols).each(function (i, col) {
                thhtml += '<td><div class="grid-th" style="overflow:hidden;height:20px;padding:2px 0;">' + col.label + '</div></td>';
            });
            if (setting.isfix) {
                thhtml += '<td style="display:none;"><div class="grid-th"></div></td>';
                thhtml += '<td><div style="width:18px;"></div></td>';
            }
            return { html: thhtml };
        },

        // build grid body (bind data)
        init_body: function () {

            var setting = this.settings, trhtml = '';

            $(setting.data).each(function (i, item) {

                trhtml += '<tr>';

                if (setting.checkbox) {
                    trhtml += '<td style="text-align:center;width:40px;"><div style=" width:40px;"><input type="checkbox" name="' + setting.id + '" value="' + item[setting.key] + '"/></div></td>'; // 选中
                }

                if (setting.rowindex) {
                    trhtml += '<td style="text-align:center;width:40px;"><div style=" width:40px;">' + (i + 1) + '</div></td>'; // 行序号
                }

                // bind row expend method
                if (setting.rowbind) {
                    setting.rowbind(i, item, setting);
                }

                $(setting.cols).each(function (j, col) {
                    trhtml += '<td><div class="grid-td" style="position:relative;overflow:hidden;height:20px;padding:2px 0;" aria-id="' + item[setting.key] + '-' + col.key + '">' + item[col.key] + '</div></td>';
                });
                if (setting.isfix) {
                    trhtml += '<td style="display:none;background-color:#ffffff;border:0;"><div class="grid-td"></div></td>';
                }
                trhtml += '</tr>';
            });

            return { html: trhtml };

        },

        // build grid body (bind pager)
        init_footer: function () {

            var setting = this.settings, pager = this.init_pager();
            var footer = '';// '<div id="' + setting.id + '-footer" style="height:38px;border:#e7eaec solid 1px;margin:0;" class="row"><div class="' + setting.id + '-pager pull-right" style="padding-right:28px;">' + pager.html + '</div></div>';//
            return { html: footer, pagerhtml: pager.html };

        },

        // build grid pager
        init_pager: function () {

            var setting = this.settings
            , pi = parseInt(setting.pageindex)
            , ps = parseInt(setting.pagesize)
            , tt = parseInt(setting.total)
            , pn = parseInt((tt / ps) + (tt % ps > 0 ? 1 : 0));

            // 验证是否可分页
            if (!pi || !ps) { return { html: '<nav><ul class="pagination" style="margin:3px 20px;"><li class="disabled"> <a href="javascript:void(0);" class="label label-info">共' + tt + '条</a></li></ul></nav>' }; }

            // 当页数等于1页时，不显示分页导航
            if (pn <= 1) { return { html: '' }; }

            var nav = '<nav><ul class="pagination" style="margin:3px 0;"><li class="disabled"> <a href="javascript:void(0);">共' + tt + '条,' + pn + '页</a></li>', num = 9; // num:可直接点击页数

            // 当页面小于等于固定页num
            if (pn <= num) {
                for (var i = 1; i <= pn ; i++) {
                    nav += '<li ' + (pi == i ? 'class="active"' : '') + '><a href="#" aria-label="' + i + '">' + i + '</a></li>';
                }
                nav += '</ul></nav>';
                return { html: nav };
            }

            // 当前为第一页时，禁用“上一页”
            nav += '<li' + ((pi == 1) ? ' class="disabled"' : '') + '><a href="javascript:void(0);" aria-label="backward"><i class="fa fa-step-backward" aria-label="backward"> </i></a></li>';
            nav += '<li' + ((pi == 1) ? ' class="disabled"' : '') + '><a href="javascript:void(0);" aria-label="Previous"><i class="fa fa-chevron-left" aria-label="Previous"> </i></a></li>';
            // 循环
            var s = pi - 4, s = s <= 0 ? 1 : (pn - s < num ? (pn - num + 1) : s), e = pi + 4, e = (e > pn) ? pn : (e - num <= 0 ? num : e);
            for (var i = s; i <= e; i++) {
                nav += '<li ' + (pi == i ? 'class="active"' : '') + '><a href="javascript:void(0);" aria-label="' + i + '">' + i + '</a></li>';
            }
            // 当前为最后一页时，禁用“下一页”
            nav += '<li' + ((pi == pn) ? ' class="disabled"' : '') + '><a href="javascript:void(0);" aria-label="Next"><i class="fa fa-chevron-right" aria-label="Next"> </i></a></li>';
            nav += '<li' + ((pi == pn) ? ' class="disabled"' : '') + '><a href="javascript:void(0);" aria-label="forward"><i class="fa fa-step-forward" aria-label="forward"> </i></a></li>';

            nav += '<li>&nbsp;<div class="btn-group"><button data-toggle="dropdown" class="btn btn-info btn-xs dropdown-toggle" style="height:27px;">跳转 <span class="caret"></span></button><ul class="dropdown-menu">';
            for (var m = (num + 1) ; m <= pn;) {
                nav += '<li><a href="javascript:void(0);" aria-label="' + m + '">' + m + '</a></li>';
                m += (parseInt(num / 2) + 1);
            }
            nav += '</ul></div></li>';

            nav += '</ul></nav>';

            return { html: nav };

        },

        event_toobar: function (isreg) {
            var thisobj = this, setting = this.settings;

            //if (!isreg)
            //    $('#' + setting.id + '-angledown').unbind();

            // body...
            // $('#' + setting.id + '-angledown').click(function () {
            //     $('#' + setting.id + '-table').toggle('fast');
            // });
        },

        event_head: function (argument) {

            var setting = this.settings;

            $('#' + setting.id + '-table').click(function (e) {
                noke_bindevent(e, 'input', checkboxevent);
            });
            var checkboxevent = function (target) {
                if (!$(target).attr('name') || $(target).attr('name').toString() != setting.id) {
                    return false;
                }

                var $list = $('#' + setting.id + '-table input[name="' + setting.id + '"]');
                var allCheckBox = $('#' + setting.id + '-table input[name="' + setting.id + '"][value="ALL_' + setting.id + '"]').get(0);
                var len = $list.length, isAllChecked = true;

                if (len <= 1)
                    return false;

                var val = $(target).attr('value');
                if (val == 'ALL_' + setting.id) {
                    for (var i = 0; i < len; i++) {
                        var t = $list.get(i);
                        var v = $(t).attr('value');
                        if (v != 'ALL_' + setting.id) {
                            t.checked = target.checked;
                        }
                    }
                    return false;

                }

                if (!target.checked) {
                    allCheckBox.checked = false;
                    return false;
                }

                for (var i = 0; i < len; i++) {
                    var t = $list.get(i);
                    var v = $(t).attr('value');
                    if (v != 'ALL_' + setting.id) {
                        isAllChecked = (isAllChecked) ? t.checked : false;
                    }
                    allCheckBox.checked = isAllChecked;
                }
            }
        },

        event_body: function (argument) {
            // body...

            var thisobj = this, setting = this.settings
            , pi = parseInt(setting.pageindex)
            , ps = parseInt(setting.pagesize)
            , tt = parseInt(setting.total)
            , pn = (tt / ps) + (tt % ps > 0 ? 1 : 0)
            , pagerfun = setting.pager;

            $('#' + setting.id + '-tbody').click(function (e) {
                noke_bindevent(e, 'div', bodyevent);
            });

            var bodyevent = function (target) {
                if (target == null) { return false; }
                var aria = $(target).attr('aria-id');
                if (aria) {

                    // save edit data
                    $('#' + setting.id + '-tbody .popover').remove();



                    var top = $(target).height();

                    var iii = aria.indexOf('-') + 1, key = aria.substr(iii, aria.length - iii);
                    
                    if (setting.edit && setting.edit[key] && setting.edit[key].editpanel) {
                        var panelcontent = setting.edit[key].editpanel;
                        var editpanel = '<div class="popover fade bottom in" role="tooltip" style="top:' + top + 'px; left:-2px; display: block;"><div class="arrow" style="left:30px;"></div><h3 class="popover-title" style="display: none;"></h3><div class="popover-content">' + panelcontent + '</div></div>';
                        $(target).append(editpanel);
                    }
                }
            };

        },

        event_footer: function (argument) {
            // body...
        },

        event_pager: function (argument) {
            // body...

            var thisobj = this, setting = this.settings
            , pi = parseInt(setting.pageindex)
            , ps = parseInt(setting.pagesize)
            , tt = parseInt(setting.total)
            , pn = parseInt((tt / ps) + (tt % ps > 0 ? 1 : 0))
            , pagerfun = setting.pager;

            // 验证是否可分页
            if (!pi || !ps || !tt || !pagerfun) { return { html: '' }; }


            $('.' + setting.id + '-pager nav').click(function (e) {
                noke_bindevent(e, 'a', pagerevent);
                noke_bindevent(e, 'i', pagerevent);
            });

            function pagerevent(target) {
                if (target == null) { return false; }
                var aria = $(target).attr('aria-label');
                if ((aria && (aria == 'Previous' || aria == 'backward') && pi == 1) || (aria && (aria == 'Next' || aria == 'forward') && pi * ps >= tt)) {
                    return false;
                }

                if (aria && aria == 'backward') {
                    setting.pageindex = 1;
                } else if (aria && aria == 'forward') {
                    setting.pageindex = pn;
                } else if (aria && aria == 'Previous') {
                    setting.pageindex = pi - 1;
                } else if (aria && aria == 'Next') {
                    setting.pageindex = pi + 1;
                } else {
                    pi = parseInt(aria);
                    if (isNaN(pi))
                        return false;
                    setting.pageindex = pi;
                }

                pagerfun(setting, function (_setting) {
                    thisobj.settings = _setting;
                    thisobj.bind();
                });

            }

        },

        isIE: function () { //https://gist.github.com/padolsey/527683
            var undef,
                v = 3,
                div = document.createElement("div"),
                all = div.getElementsByTagName("i");

            while (
                div.innerHTML = "<!--[if gt IE " + (++v) + "]><i></i><![endif]-->",
                all[0]
            ) {
                return v > 4 ? v : undef;
            }
        },

        remove: function () {
            this.element.off("." + pluginName);
            this.element.removeData(pluginName);
        },

        _get: function (ids) {
            var setting = this.settings, data = setting.data, key = setting.key, res = [];
            if (!data || data.length <= 0 || !ids || ids.length <= 0)
                return null;

            var len = data.length;
            for (var i = 0; i < len; i++) {
                if (ids.indexOf(data[i][key].toString()) >= 0)
                    res.push(data[i]);
            }
            return res;
        },
       
        GetChecked: function () {
            var setting = this.settings, $list = $('#' + setting.id + '-table input[name="' + setting.id + '"]'), len = $list.length, res = { ids: [], data: [] };

            if (len <= 1) { return res; }

            for (var i = 0; i < len; i++) {
                var t = $list.get(i);
                var v = $(t).attr('value');
                if (v != 'ALL_' + setting.id && t.checked) { res.ids.push(v.toString()); }
            }

            res.data = this._get(res.ids);

            if (res.data == null) { res.data = []; }
            return res;
        },

        GetSetting: function () {
            return this.settings;
        },

        Get: function (id) {
            var res = this._get([id]);
            if (res == null || res.length == 0) { return null; }
            return res[0];
        },

    };


    $.fn[pluginName] = function (options) {

        if (!options) {
            if (this.data(pluginName)) {
                return this.data(pluginName);
            }
            return null;
        }

        this.each(function () {
            var el = $(this);
            if (el.data(pluginName)) {
                el.data(pluginName).remove();
                el.data(pluginName, new Plugin(this, options));
            } else {
                el.data(pluginName, new Plugin(this, options));
            }
        });
        return this;
    };


})(jQuery, window, document);

var noke_bindevent = function (e, nodeName, callback){
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (target.nodeName.toString().toLocaleUpperCase() == nodeName.toLocaleUpperCase()) {
        callback(target);
        return false;
    }
    callback(null);
};



function noke_gridscroll(tag, id) {
    var t = tag.scrollLeft;
    if (t || t == 0) {
        $('#' + id + '-thead').scrollLeft(t);
    }
}